package com.cxyjy.pptdemoapi.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cxyjy.common.util.JFileUtil;
import com.cxyjy.common.util.JObjectUtil;
import com.cxyjy.common.util.JResponse;
import com.cxyjy.common.util.ResultUtil;
import com.cxyjy.pptdemoapi.service.PPTCreateService;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.net.ssl.*;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.cxyjy.common.constants.PPTCreateConstants.*;
import static com.cxyjy.common.util.ResultCode.NO_PPT_FILE_FOUNDED;

/**
 * @Author: JrsJony
 * @Date : 2025/1/20 15:54
 */
@Service("PPTCreateService")
public class PPTCreateServiceImpl implements PPTCreateService {

    @Override
    public void createOutline(String textStr, HttpServletResponse httpServletResponse) throws IOException, NoSuchAlgorithmException, KeyManagementException {
        if (JObjectUtil.isEmpty(textStr)) {
            return;
        }
        List<Map<String, Object>> messages = new ArrayList<>();
        Map<String, Object> messageMap = new HashMap<>();
        List<Map<String, Object>> contentList = new ArrayList<>();
        Map<String, Object> contentMap = new HashMap<>();
        contentMap.put("type", "text");
        contentMap.put("text", textStr + "根据以上文字给我输出一个纯净的大纲，不要带其他任何对话相关的文字，我这是调用接口" );
        contentList.add(contentMap);

        messageMap.put("role", "user");
        messageMap.put("content", contentList);
        messages.add(messageMap);
//        APIKEY:47d48779b5ad45858619b8c089ef54d8.udxlYxucWApHxq4D
        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("assistant_id", "65d2f07bb2c10188f885bd89");//PPT助手（官方）	超实用的PPT生成器，支持手动编辑大纲、自动填充章节内容。 assistant id:65d2f07bb2c10188f885bd89
        paramsMap.put("conversation_id", null);
        paramsMap.put("model", "glm-4-assistant");
        paramsMap.put("stream", true);
        paramsMap.put("messages", messages);
        paramsMap.put("attachments", null);
        paramsMap.put("metadata", null);
        sendCreateOutlinePost(paramsMap, httpServletResponse);


    }

    @Override
    public void createPpt(String usrText, String conversationId, HttpServletResponse response) throws NoSuchAlgorithmException, IOException, KeyManagementException {
        if (JObjectUtil.isEmpty(usrText)) {

        }
        List<Map<String, Object>> messages = new ArrayList<>();
        Map<String, Object> messageMap = new HashMap<>();
        List<Map<String, Object>> contentList = new ArrayList<>();
        Map<String, Object> contentMap = new HashMap<>();
        contentMap.put("type", "text");
        contentMap.put("text", "生成PPT");
        contentList.add(contentMap);

        messageMap.put("role", "user");
        messageMap.put("content", contentList);
        messages.add(messageMap);
//        APIKEY:47d48779b5ad45858619b8c089ef54d8.udxlYxucWApHxq4D
        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("assistant_id", "65d2f07bb2c10188f885bd89");//PPT助手 assistant id:65d2f07bb2c10188f885bd89
        paramsMap.put("conversation_id", conversationId);
        paramsMap.put("model", "glm-4-assistant");
        paramsMap.put("stream", true);
        paramsMap.put("messages", messages);
        paramsMap.put("attachments", null);
        paramsMap.put("metadata", null);
        createPptPost(paramsMap,response);
    }

    @Override
    public JResponse zhipuFileUpload(MultipartFile multipartFile, String purpose) throws IOException {
//        String fileName = multipartFile.getOriginalFilename();
        File file = JFileUtil.multipartfileToFile(multipartFile);
        if(!JFileUtil.checkFileExtension(multipartFile, new String[]{"ppt", "pptx"})){
            return ResultUtil.error(NO_PPT_FILE_FOUNDED);
        }
        String boundary = "-------------------------" + JObjectUtil.stringValue(System.currentTimeMillis());
        String CRLF = "\r\n"; // 换行符
        HttpURLConnection conn = (HttpURLConnection) ZHIPU_UPLOAD_FILE_URL.openConnection();
        conn.setDoOutput(true);
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);

        try (
                OutputStream output = conn.getOutputStream();
                PrintWriter writer = new PrintWriter(new OutputStreamWriter(output, "UTF-8"), true);
        ) {
            // 发送文件数据
            writer.append("--" + boundary).append(CRLF);
            writer.append("Content-Disposition: form-data; name=\"" + "image" + "\"; filename=\"" + file.getName() + "\"").append(CRLF);
            writer.append("Content-Type: " + URLConnection.guessContentTypeFromName(file.getName())).append(CRLF);
            writer.append(CRLF).flush();

            Files.copy(file.toPath(), output);
            output.flush(); // 确保文件数据发送完毕

            writer.append(CRLF).flush(); // 结束行数据
            writer.append("--" + boundary + "--").append(CRLF);
        }
        StringBuilder response = new StringBuilder();
        BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        String inputLine;
        while (JObjectUtil.isNotEmpty(inputLine = in.readLine())) {
            response.append(inputLine);
        }
        in.close();
        conn.disconnect();
        return ResultUtil.success(JObjectUtil.stringValue(response));
    }

    /**生成PPT*/
    private void createPptPost(Map<String,Object> paramsMap, HttpServletResponse response) throws NoSuchAlgorithmException, KeyManagementException, IOException {
        // 以下是处理 SSL 证书信任的代码
        TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    @Override
                    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    }

                    @Override
                    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    }

                    @Override
                    public X509Certificate[] getAcceptedIssuers() {
                        return new X509Certificate[0];
                    }
                }
        };

        SSLContext sslContext = SSLContext.getInstance("SSL");
        sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());

        // 忽略主机名验证
        HostnameVerifier allHostsValid = (hostname, session) -> true;
        HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);

        //————————————————————————————————————————————————————
        HttpURLConnection connection = (HttpURLConnection) CREATE_PPT_URL.openConnection();
        connection.setRequestMethod("POST");
        connection.setDoOutput(true);
        connection.setDoInput(true);  // 接收响应数据
        // 设置请求头,  其中有重要的apikey
        connection.setRequestProperty("Content-Type", "application/json");
        connection.setRequestProperty("Authorization", "Bearer " + ZHIPU_API_KEY);

        //发送请求体内容
        try (OutputStream os = connection.getOutputStream()) {
            byte[] input = JSON.toJSONString(paramsMap).getBytes(StandardCharsets.UTF_8);
            os.write(input, 0, input.length);
        }
        if (connection.getResponseCode() != 200) {
            throw new IOException("API request failed with response code: " + connection.getResponseCode());
        }
        // 先设置响应编码
        response.setContentType("text/plain; charset=UTF-8");
        response.setCharacterEncoding("UTF-8");

        // 获取输入流（流式响应）
        try (InputStream inputStream = connection.getInputStream();
             BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
             PrintWriter out = response.getWriter()) {

            System.out.println("响应编码: " + response.getCharacterEncoding());

            String line;
            StringBuilder responseBuilder = new StringBuilder();
            while ((line = reader.readLine()) != null) {
                System.out.println("原始数据: " + line);
                if (line.startsWith("data:")) {
                    line = line.substring(5).trim();
                    if (JObjectUtil.isValidJson(line)) {
                        try {
                            Map<String, Object> lineMap = JObjectUtil.toMap(JSONObject.parse(line));
                            if (JObjectUtil.stringValue(lineMap.get("status")).equals("in_process")) {
                                List<Map<String, Object>> choices = JObjectUtil.jsonArrayToList(lineMap.get("choices"), Map.class);
                                Map<String, Object> choiceMap = choices.get(0);
                                Map<String, Object> deltaMap = (Map) choiceMap.get("delta");
                                String content = JObjectUtil.stringValue(deltaMap.get("content"));
                                if(JObjectUtil.isNotEmpty(content)){
                                    responseBuilder.append(content);
                                }
                                // 将内容发送给前端
                                out.print(content);
                                out.flush();
                            }
                        } catch (Exception e) {
                            // 记录解析异常日志
                            System.err.println("Error parsing JSON: " + e.getMessage());
                        }
                    }
                }
            }
            System.out.println(JObjectUtil.stringValue(responseBuilder));
        }

    }
    /**
     * 接受生成大纲的流式响应，逐条发送给前端
     * @param paramsMap
     * @param response
     * @throws IOException
     * @throws NoSuchAlgorithmException
     * @throws KeyManagementException
     */
    private void sendCreateOutlinePost(Map<String, Object> paramsMap, HttpServletResponse response) throws IOException, NoSuchAlgorithmException, KeyManagementException {
        // 以下是处理 SSL 证书信任的代码
        TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    @Override
                    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    }

                    @Override
                    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    }

                    @Override
                    public X509Certificate[] getAcceptedIssuers() {
                        return new X509Certificate[0];
                    }
                }
        };

        SSLContext sslContext = SSLContext.getInstance("SSL");
        sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());

        // 忽略主机名验证
        HostnameVerifier allHostsValid = (hostname, session) -> true;
        HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);

        //——————————————————————————————————————————————————
        HttpURLConnection connection = (HttpURLConnection) CREATE_PPT_URL.openConnection();
        connection.setRequestMethod("POST");
        connection.setDoOutput(true);
        connection.setDoInput(true);  // 接收响应数据
        // 设置请求头,  其中有重要的apikey
        connection.setRequestProperty("Content-Type", "application/json");
        connection.setRequestProperty("Authorization", "Bearer " + ZHIPU_API_KEY);

        //发送请求体内容
        try (OutputStream os = connection.getOutputStream()) {
            byte[] input = JSON.toJSONString(paramsMap).getBytes(StandardCharsets.UTF_8);
            os.write(input, 0, input.length);
        }
        if (connection.getResponseCode() != 200) {
            throw new IOException("API request failed with response code: " + connection.getResponseCode());
        }
        // 先设置响应编码
        response.setContentType("text/plain; charset=UTF-8");
        response.setCharacterEncoding("UTF-8");
        // 获取输入流（流式响应）
        try (InputStream inputStream = connection.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            PrintWriter out = response.getWriter()) {

//            response.setContentType("text/plain; charset=UTF-8");
            System.out.println("响应编码: " + response.getCharacterEncoding());


            String conversationId = null;
            boolean idSet = false;
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println("原始字节数组长度: " + line.getBytes().length);
                System.out.println("原始数据: " + line);
                if (line.startsWith("data:")) {
                    line = line.substring(5).trim();
                    if (JObjectUtil.isValidJson(line)) {
                        try {
                            Map<String, Object> lineMap = JObjectUtil.toMap(JSONObject.parse(line));
                            if(!idSet){
                                conversationId = JObjectUtil.stringValue(lineMap.get("conversation_id"));
                                if(JObjectUtil.isNotEmpty(conversationId)){
                                    response.setHeader("conversationId",conversationId);
                                    idSet = true;
                                }
                            }
                            if (JObjectUtil.stringValue(lineMap.get("status")).equals("in_process")) {
                                List<Map<String, Object>> choices = JObjectUtil.jsonArrayToList(lineMap.get("choices"), Map.class);
                                Map<String, Object> choiceMap = choices.get(0);
                                Map<String, Object> deltaMap = (Map) choiceMap.get("delta");
                                String content = JObjectUtil.stringValue(deltaMap.get("content"));
                                // 将内容发送给前端
                                out.print(content);
                                out.flush();
                            }
                        } catch (Exception e) {
                            // 记录解析异常日志
                            System.err.println("Error parsing JSON: " + e.getMessage());
                        }
                    }
                }
            }
        }

    }

}
